// Learn TypeScript:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/2.4/manual/en/scripting/life-cycle-callbacks.html

const { ccclass, property } = cc._decorator;

@ccclass
export default class draw extends cc.Component {

    @property({ type: cc.Texture2D, displayName: '笔尖tex图' })
    nibTexture: cc.Texture2D = null;

    //笔尖像素点数据
    nibTexArrBuf: Uint8Array;

    canvasTexArrBuf: Uint8Array;

    canvasTex: cc.Texture2D;
    // LIFE-CYCLE CALLBACKS:
    lastPos: cc.Vec2;
    // onLoad () {}
    isCanDraw: boolean = false;
    //纯色画笔颜色
    pureBrushColor: cc.Color = cc.color().fromHEX(("#ff0000"));

    start() {
        this.init()
    }

    init() {
        this.nibTexArrBuf = this.getTexturePixel(this.nibTexture);
        this.canvasTex = new cc.Texture2D();
        this.canvasTexArrBuf = new Uint8Array(this.node.height * this.node.width * 4).fill(255)
        this.canvasTex.initWithData(
            this.canvasTexArrBuf,
            cc.Texture2D.PixelFormat.RGBA8888,
            this.node.width,
            this.node.height
        );
        this.node.getComponent(cc.Sprite).spriteFrame = new cc.SpriteFrame(this.canvasTex)
        this.addEvent()
        this.isCanDraw = true
    }

    addEvent() {
        this.node.on(cc.Node.EventType.TOUCH_START, (event) => {
            if (!this.isCanDraw) {
                return
            }
            let position = this.node.parent.convertToNodeSpaceAR(event.getLocation());
            this.lastPos = position;
            this.drawCanvas(position)
        }, this)

        this.node.on(cc.Node.EventType.TOUCH_MOVE, (event) => {
            if (!this.isCanDraw) {
                return
            }
            let position = this.node.parent.convertToNodeSpaceAR(event.getLocation());
            let len = position.sub(this.lastPos).len();
            let drawStep = this.getDrawStrp();

            if (len < drawStep) return;

            //两个点移动的距离步长比值
            let count = Math.round(len / drawStep);
            //归一化确定方向
            let dir = position.sub(this.lastPos).normalize();
            //根据方向和点之间的比值放大向量确定偏移值
            let delta = dir.mul(drawStep);
            for (let i = 0; i < count; i++) {
                this.lastPos.addSelf(delta);
                this.drawCanvas(this.lastPos);
            }
        }, this)

        this.node.on(cc.Node.EventType.TOUCH_END, () => {

        }, this)

        this.node.on(cc.Node.EventType.TOUCH_CANCEL, () => {

        }, this);
    }

    /**向量移动多次才进行一次绘画 */
    getDrawStrp(): number {
        return 1
        return Math.floor(
            new cc.Vec2(this.nibTexture.width, this.nibTexture.height).len() / 1.4
        );
    }

    drawCanvas(position: cc.Vec2) {
        let nibWidth = this.nibTexture.width
        let nibHeight = this.nibTexture.height
        for (let i = 0; i < nibHeight; i++) {
            for (let j = 0; j < nibWidth; j++) {
                let x = Math.floor(
                    position.x +
                    this.node.width / 2 +
                    j -
                    nibWidth / 2
                );
                let y = Math.floor(
                    -position.y +
                    this.node.height / 2 +
                    i -
                    nibHeight / 2
                );

                let s = (y * this.node.width + x) * 4;
                let a = (i * nibWidth + j) * 4;

                if (
                    x >= this.node.width ||
                    y >= this.node.width ||
                    x < 0 ||
                    y < 0
                )
                    continue;

                if (typeof this.canvasTexArrBuf[s] === "undefined") {
                    break;
                }

                if (this.nibTexArrBuf[a + 3] === 0) {
                    continue;
                }
                this.canvasTexArrBuf[s] = this.pureBrushColor.r;
                this.canvasTexArrBuf[s + 1] = this.pureBrushColor.g;
                this.canvasTexArrBuf[s + 2] = this.pureBrushColor.b;
                this.canvasTexArrBuf[s + 3] = this.pureBrushColor.a;
            }
        }
    }

    /**获取Texture2D的像素点数组 */
    getTexturePixel(tex: cc.Texture2D): Uint8Array {
        let rt = new cc.RenderTexture();
        rt.initWithSize(tex.width, tex.height);
        cc.renderer.device.setFrameBuffer(rt._framebuffer);
        rt.drawTextureAt(tex, 0, 0);
        // data就是这个texture的rgba值数组
        let data = rt.readPixels(null, 0, 0, tex.width, tex.height);
        return data;
    }

    protected update(dt: number): void {
        if (this.isCanDraw) {
            this.canvasTex.initWithData(
                this.canvasTexArrBuf,
                cc.Texture2D.PixelFormat.RGBA8888,
                this.node.width,
                this.node.height
            );
        }
    }
}
